package com.zlm.realtime.utils

import io.searchbox.client.config.HttpClientConfig
import io.searchbox.client.{JestClient, JestClientFactory}
import io.searchbox.core._
import org.elasticsearch.index.query.{BoolQueryBuilder, MatchQueryBuilder, TermQueryBuilder}
import org.elasticsearch.search.builder.SearchSourceBuilder
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder
import org.elasticsearch.search.sort.SortOrder

import java.util

/**
 * @author Harbour 
 * @date 2021-03-31 21:49
 */
object MyESUtils {

    private var factory : JestClientFactory = null

    def getClient : JestClient = {
        if (factory == null) build()
        factory.getObject
    }

    /**
     * 注意：服务器性能太差，所以连接超时时长要设置长一点
     */
    def build (): Unit = {

        // 将scala的List转java的List
        import scala.collection.JavaConverters._
        val esURLs: util.List[String] = MyPropertiesUtils.getProperty("es.hosts").split(",").toList.asJava

        factory = new JestClientFactory
        factory.setHttpClientConfig(
            new HttpClientConfig.Builder(esURLs)
              .multiThreaded(true)
              .maxTotalConnection(20)
              .connTimeout(60 * 1000)
              .readTimeout(60 * 1000)
              .build()
        )
    }

    def queryIndex(): Unit = {
        val client: JestClient = getClient

        val searchSourceBuilder = new SearchSourceBuilder

        val boolQueryBuilder: BoolQueryBuilder = new BoolQueryBuilder()
        boolQueryBuilder.must(new MatchQueryBuilder("name", "red"))
        boolQueryBuilder.filter(new TermQueryBuilder("actorList.name.keyword","zhang han yu"))
        searchSourceBuilder
          .from(0)
          .size(20)
          .sort("doubanScore", SortOrder.DESC)
          .highlighter(new HighlightBuilder().field("name"))
        searchSourceBuilder.query(boolQueryBuilder)

        val query: String = searchSourceBuilder.toString()

        val search: Search = new Search.Builder(query)
          .addIndex("movie_index")
          .build()
        val result: SearchResult = client.execute(search)
        val list: util.List[SearchResult#Hit[util.Map[String, Any], Void]] =
            result.getHits(classOf[util.Map[String, Any]])

        //将 Java 转换为 Scala 集合，方便操作
        import scala.collection.JavaConverters._
        val list1: List[util.Map[String, Any]] = list.asScala.map(_.source).toList
        println(list1.mkString("\n"))

        client.close()
    }

    /**
     * 1. 获取es操作工具
     * 2. 创建es操作对象
     * 3. 执行操作
     * 4. 关闭连接
     * @param infoList 待插入的数据列表
     * @param indexName 索引名 （ES表名）
     */
    def bulkInsert(infoList: List[Any], indexName: String): Unit = {
        val client: JestClient = getClient
        val bulkBuilder = new Bulk.Builder
        if (infoList != null && infoList.nonEmpty) {
            for (info <- infoList) {
                val index: Index = new Index.Builder(info)
                  .index(indexName)
                  .`type`("_doc")
                  .build()
                bulkBuilder.addAction(index)
            }
        }
        val bulk: Bulk = bulkBuilder.build()
        val result: BulkResult = client.execute(bulk)
        val items: util.List[BulkResult#BulkResultItem] = result.getItems
        println("保存到 ES " + items.size() + " 条数据")
        //关闭连接
        client.close()
    }

    def main(args: Array[String]): Unit = {
        queryIndex()
    }

}
